go-zero api 文件生成项目框架
数据结构
.api 文件是 go-zero 自创的文件格式,和 protobuf 的语法有很大不同,但好在不难理解。具体语法介绍可看官网文档:go-zero.dev/docs/tasks/…
先编写接口定义,然后直接一次性使用 goctl 生成代码。
api 文件支持将一个数据结构嵌入另一个结构中,便于编写统一的响应格式。
首先定义空请求结构和基础的响应结构:
txt
syntax = "v1"
type Empty {
}
type BasicResponse {
StatusCode int32 `json:"status_code"`
StatusMsg string `json:"status_msg"`
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
type 关键字也支持代码块,只需要用 type()
包裹,就可以省去关键词。下面定义了注册和登录的请求和响应结构。
go
type (
RegisterRequest struct {
Username string `form:"username"`
Password string `form:"password"`
}
RegisterResponse struct {
BasicResponse
UserId int64 `json:"user_id"`
}
)
type (
LoginRequest struct {
Username string `form:"username"`
Password string `form:"password"`
}
LoginResponse struct {
BasicResponse
UserId int64 `json:"user_id"`
}
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
最后还要定义一个获取用户信息的接口。因为本文不涉及创作、社交方面的业务逻辑实现,所以 User
结构其实没什么可以返回的信息。之后将其嵌入响应类型的 user
字段中:
go
type (
User {
Id int64 `json:"id"`
Name string `json:"name"`
}
GetUserInfoRequest struct {
UserId int64 `form:"user_id"`
}
GetUserInfoResponse struct {
BasicResponse
User User `json:"user"`
}
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
定义接口路由
把所有 api 路由配置好
txt
@server(
group: app
)
service app {
@handler Ping
get /ping (Empty) returns (BasicResponse)
}
@server(
group: user
prefix: /douyin/user
)
service app {
@handler Register
post /register (RegisterRequest) returns (RegisterResponse)
@handler Login
post /login (LoginRequest) returns (LoginResponse)
@handler GetUserInfo
get / (GetUserInfoRequest) returns (GetUserInfoResponse)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
以下几点需要注意:
- 如果 service 代码块有多个,要求后面的名称(即 “app”)相同
- 形如装饰器的 @server 代码块可以做代码分组、路由前缀、鉴权、中间件等多种配置。
- 这里把路由分成 app 和 user 两组,之后生成时会分组放在文件夹里
- 给 user 组设置了
/douyin/user
的路由器前缀,就不用重复写了 - 鉴权和中间件配置下文会提到
- 每个接口需要一个
handler
,其实就是给函数起名 - 接口定义的格式是
<HTTP方法> <子路径> (<请求数据结构>) returns (<响应数据结构>)
创建项目模板
这次不是新建示例项目,而是根据现有的 api 声明创建
安装 goctl
https://go-zero.dev/docs/tasks/installation/goctl
bash
$ GO111MODULE=on go install github.com/zeromicro/go-zero/tools/goctl@latest
1
安装 protoc
https://go-zero.dev/docs/tasks/installation/protoc
bash
$ goctl env check --install --verbose --force
1
shell
goctl api go --api app.api --dir=. --style=goZero
1
这会在当前目录生成项目文件。之后进入目录安装依赖:
shell
go mod tidy
1
测试 Ping 接口
Ping 接口的逻辑在 internal/logic/app/pingLogic.go
,打开文件并编辑 handler 函数:
go
func (l *PingLogic) Ping(req *types.Empty) (resp *types.BasicResponse, err error) {
return &types.BasicResponse{
StatusCode: 0,
StatusMsg: "pong",
}, nil
}
1
2
3
4
5
6
2
3
4
5
6
这里的写法和 rpc 微服务有点区别。注意到传入的 resp
是一个指针,所以需要手动创建一个响应结构体并设置键值。
这样就算完成 Ping 接口了,可以运行服务。